import {WIDGET_TYPE} from "./widget/widget-const.js"
import "./slog-math.js"
import D from "./delegator.js"

const _DOC = window.document;
const _BODY = _DOC.body;

function _GenID() {
    // Math.random should be unique because of its seeding algorithm.
    // Convert it to base 36 (numbers + letters), and grab the first 9 characters
    // after the decimal.
    return 'toc_' + Math.random().toString(36).substr(2, 9);
};

function _InstantiateElement(qString, clone = true, index = 0) {
    let _elem = _BODY.querySelector(qString);
    if(!_elem) {
        console.warn(`no such template: ${qString}`);
        return;
    }
    if(index < 0 || index >= _elem.content.childElementCount) {
        console.warn(`no such child element at index: ${index}`);
        return;
    }
    _elem = _elem.content.children[index];
    return clone ? _elem.cloneNode(true) : _elem;
}


export function UISearch() {
    const _elem = _InstantiateElement("#ID_tpl_search", false);
    const _inputElem = D(_elem).Qe('[search-input]');
    const _resultElem = D(_elem).Qe('[search-result]');
    const _modal = UIModal(_elem, true);


    const _CreateItem = function (name, desc, tag, score) {
        const _elem = _InstantiateElement("#ID_tpl_search", true, 0);
        D(_elem).Qe('[search-result-name]').innerText = name;
        D.Qe('[search-result-desc]').innerText = desc;
        D.Qe('[search-result-tag]').innerText = tag;
        D.Qe('[search-result-score]').innerText = score;
        return _elem;
    }


    const Show = () => {_modal.Show();}
    const Hide = () => {_modal.Hide();}
    return {
        BeforeAdd() {
            D(_resultElem).AddStyle('display', 'none');
        },
        EndAdd() {
            D(_resultElem).AddStyle('display', 'block');
        },
        AddItem(ID,name, desc, tag, score) {
            const _e = _CreateItem(name, desc, tag, score);
            D(_e).SetID(ID);
            _resultElem.append(_e);
        },
        Show, Hide,
        get closeBtn() {return _modal.closeBtn;},
        get inputElem() {return _inputElem;},
        get resultElem() {return _resultElem;},
        get element() {return _elem;},
    }
}

export function UILogin() {
    const _elem = _InstantiateElement('#ID_login', false, 0);
    //D(_elem).Qe("h3").textContent = 'Property';
    const _confirmBtn = D(_elem).Qe("#ID_property_confirm");
    const _cancelBtn = D.Qe("#ID_property_cancel");
    const _closeBtn = D.Qe("#ID_close");
    const _modal = UIModal(_elem, false);

    const Show = () => {_modal.Show();}
    const Hide = () => {_modal.Hide();}
    return {
        Show, Hide,
        get comfirmBtn() {return _confirmBtn;},
        get cancelBtn() {return _cancelBtn;},
        get closeBtn() {return _closeBtn;},
    }
}

export function UIProperty() {
    const _elem = _InstantiateElement('#ID_tpl_property', false, 0);
    const _modal = UIModal(_elem, false);
    const _confirmBtn = D(_elem).Qe("[property-confirm]");
    const _deleteBtn = D.Qe("[property-delete]");
    const _createBtn = D.Qe("[property-create]");
    const _closeBtn = D.Qe("[property-close]");

    const Show = () => {_modal.Show();}
    const Hide = () => {_modal.Hide();}
    return {
        Show, Hide,
        SetTagGroup(tagGroup) {
            D(_elem).Qe("[property-tag]").append(tagGroup.element);
        },
        SetButtonAction(closeFn, confirmFn, deleteFn, createFn) {
            if(closeFn) {_closeBtn.onclick = closeFn; D(_closeBtn).RemoveStyle('display');} else {D(_closeBtn).AddStyle('display', 'none');}
            if(confirmFn) {_confirmBtn.onclick = confirmFn; D(_confirmBtn).RemoveStyle('display');} else {D(_confirmBtn).AddStyle('display', 'none');}
            if(createFn) {_createBtn.onclick = createFn; D(_createBtn).RemoveStyle('display');} else {D(_createBtn).AddStyle('display', 'none');}
            if(deleteFn) {_deleteBtn.onclick = deleteFn; D(_deleteBtn).RemoveStyle('display');} else {D(_deleteBtn).AddStyle('display', 'none');}
        },
        SetTitle(caption) {D(_elem).Qe('[property-title]').innerText = caption;},
        SetData(name, modifyTime, createTime, description, toc, property, publish) {
            D(_elem).Qe('[property-description]').innerText = description ?? "";
            D(_elem).QeC('[property-name]').SetInputValue(name ?? "");
            D(_elem).QeC('[property-modifyTime]').SetInputValue(modifyTime ?? new Date());
            D(_elem).QeC('[property-createTime]').SetInputValue(createTime ?? new Date());
            D(_elem).QeC('#checkboxa').SetInputValue(publish ?? false);
            D(_elem).QeC('#checkboxb').SetInputValue(toc ?? true);
            D(_elem).QeC('#checkboxc').SetInputValue(property ?? true);
        },
        GetData(obj) {
            obj.description = D(_elem).Qe('[property-description]').innerText;
            obj.name = D(_elem).QeC('[property-name]').GetInputValue();
            obj.modifyTime = D(_elem).QeC('[property-modifyTime]').GetInputValue();
            obj.createTime = D(_elem).QeC('[property-createTime]').GetInputValue();
            obj.publish = D(_elem).QeC('#checkboxa').GetInputValue();
            obj.toc = D(_elem).QeC('#checkboxb').GetInputValue();
            obj.property = D(_elem).QeC('#checkboxc').GetInputValue();
        },
    }
}

function UIModal(contentElement, showCloseButton) {
    const _elem = _InstantiateElement('#ID_tpl_modal', true, 0);
    const _closeBtn = D(_elem).Qe('[modal-close]');
    if(!showCloseButton) _closeBtn.remove();
    _elem.append(contentElement);

    const Show = () => {
        _BODY.append(_elem);
    }
    const Hide = () => {
        _elem.remove();
    }

    return {
        Show, Hide,
        get closeBtn() {return _closeBtn;}
    }
}

const UICollapserTriggerType = Object.freeze({
    CLICK: 1,
    ENTER: 2,
    OVER: 3,
});
const _DELAY_TIME_ = 0;//ms
function Collapser(triggerElement, targetElement, triggerType = UICollapserTriggerType.CLICK) {
    let _visible = true;

    D(targetElement).AddClass('anim-height');
    targetElement.ontransitionend = e => {
        D(targetElement).AddStyle('height', 'auto').AddStyle('display', _visible ? 'block' : 'none');
    };
    const Expand = () => {
        D(targetElement).AddStyle('display', 'block').AddStyle("height", '0px');

        setTimeout(_ => {
            D(triggerElement).ReplaceClass('rotate-0', 'rotate-90');
            D(targetElement).AddStyle("height", `${targetElement.scrollHeight}px`);
            _visible = true;
        }, _DELAY_TIME_);
    }
    const Collapse = () => {
        D(targetElement).AddStyle("height", `${targetElement.scrollHeight}px`);

        setTimeout(_ => {
            D(triggerElement).ReplaceClass('rotate-90', 'rotate-0');
            D(targetElement).AddStyle("height", '0px');
            _visible = false;
        }, _DELAY_TIME_);
    }
    switch(triggerType) {
        case UICollapserTriggerType.CLICK:
            triggerElement.onclick = e => {
                _visible ? Collapse() : Expand();
                e.stopImmediatePropagation();
            };
            break;
        case UICollapserTriggerType.ENTER:
            triggerElement.onmouseenter = Expand;
            triggerElement.onmouseleave = Collapse;
            break;
        case UICollapserTriggerType.OVER:
            triggerElement.onmouseover = Expand;
            triggerElement.onmouseout = Collapse;
            break;
    }
    return {
        Expand, Collapse,
        IsExpanded() {return _visible;},
        Release() {
            D(targetElement).RemoveClass('anim-height');
            switch(triggerType) {
                case UICollapserTriggerType.CLICK:
                    triggerElement.onclick = undefined;
                    break;
                case UICollapserTriggerType.ENTER:
                    triggerElement.onmouseenter = undefined;
                    triggerElement.onmouseleave = undefined;
                    break;
                case UICollapserTriggerType.OVER:
                    triggerElement.onmouseover = undefined;
                    triggerElement.onmouseout = undefined;
                    break;
            }
        }
    }
}

const COLOR_PRE_DEPTH = 10;// 0~255; 
function _GetBackgroundColor(depth) {
    const _color = depth * COLOR_PRE_DEPTH;
    return `rgba(${250 - _color},${253 - _color},${255 - _color},1.0)`;
}
export function UIPageListItem() {
    const _elem = _InstantiateElement('#ID_tpl_page_list_item');
    const _con = D(_elem).Qe("[item-container]");
    const _indicator = D(_elem).Qe("[item-indicator]");
    const _nameElem = D(_elem).Qe("[item-name]");
    const _collapserBtn = D(_elem).Qe("[item-collapser]");

    const _collaper = Collapser(_collapserBtn, _con);
    const _firstElement = _elem.firstElementChild;

    const Active = () => {
        D(_firstElement).AddAttribute('active', '');
    }
    const Deactive = () => {
        D(_firstElement).RemoveAttribute('active');
    }
    const Expand = () => {
        _collaper.Expand();
    }
    const Collapse = () => {
        _collaper.Collapse();
    }

    return {
        Expand, Collapse, Active, Deactive, 
        Release() {
            _elem.remove();
            _collaper.Release();
        },
        SetName(name) {_nameElem.innerText = name;},
        SetPID(PID) {_firstElement.id = PID;},
        get element() {return _elem;},
        get containerElement() {return _con;},
        SetOffsetSize(size) {
            const _rgb = _GetBackgroundColor(size);
            D(_con).AddStyle("background-color", _rgb);
            D(_nameElem).AddStyle("margin-left", `${size / 2}rem`);
        },
        HideCollaperButton() {
            D(_collapserBtn).AddStyle("display", "none");
        },
        ShowCollaperButton() {
            D(_collapserBtn).AddStyle("display", "auto");
        },
    }
}

const UIDraggerDirection = Object.freeze({
    LEFT: 1,
    RIGHT: 2,
    TOP: 3,
    BOTTOM: 4,
});
export {UIDraggerDirection};
let _x = 0;
let _y = 0;
export function UIDragger(dragger, target, direction, minSize = 0, maxSize = 300, enabled = true) {
    if(!target) return undefined;
    D(target).AddStyle('userSelect', 'auto');

    let _enabled = false;
    let _w = 0;
    let _h = 0;

    const mouseDownHandler = function (e) {
        _x = e.clientX;
        _y = e.clientY;

        _w = parseInt(target.offsetWidth, 10);
        _h = parseInt(target.offsetHeight, 10);

        // Attach the listeners to `_DOC`
        _DOC.onmousemove = mouseMoveHandler;
        _DOC.onmouseup = mouseUpHandler;
    };

    const mouseMoveHandler = function (e) {
        const dx = e.clientX - _x;
        const dy = e.clientY - _y;

        if(direction < UIDraggerDirection.TOP) {
            const _ww = Math.clamp(minSize, maxSize, _w + dx);
            D(target).AddStyle('width', `${_ww}px`);
        } else {
            const _hh = Math.clamp(minSize, maxSize, _h + dy);
            D(target).AddStyle('height', `${_hh}px`);
        }
        e.stopImmediatePropagation();
    };

    const mouseUpHandler = function () {
        _DOC.onmousemove = undefined;
        _DOC.onmouseup = undefined;
    };

    const Enable = function () {
        if(!_enabled) {
            target.append(dragger);
            dragger.onmousedown = mouseDownHandler;
            _enabled = true;
        }
    }
    const Disable = function () {
        if(_enabled) {
            dragger.remove();
            dragger.onmousedown = undefined;
            _enabled = false;
        }
    }
    if(enabled) {
        Enable();
    }
    return {Enable, Disable};
}

export function UIToggleButton(queryString, turnOn = true) {
    const _elem = _BODY.querySelector(queryString);
    if(!_elem) {
        console.warn("no such element");
        return;
    }
    const _first = _elem.firstElementChild;
    const _second = _elem.lastElementChild;
    const On = function () {
        if(turnOn) return;
        _second.replaceWith(_first);
        turnOn = true;
    }
    const Off = function () {
        if(!turnOn) return;
        _first.replaceWith(_second);
        turnOn = false;
    }
    turnOn ? _second.remove() : _first.remove();
    return {On, Off, get element() {return _elem;} };
}

const _WIDGET_TOOL_BOTTOM_ = -50;
export function UIWidgetTool() {
    const _elem = _DOC.querySelector('#ID_main_content_widget_tool');
    const _sidebar = _DOC.querySelector('#ID_sidebar');
    const _ro = new ResizeObserver(entries => {
        D(_elem);
        for(let entry of entries) {
            if(entry.target === _sidebar) {
                D.AddStyle('left', `${entry.borderBoxSize[0].inlineSize + 20}px`);//20px is gap;
            } else {
                D.AddStyle('width', `${entry.borderBoxSize[0].inlineSize}px`);
            }
        }
    });
    _ro.observe(_DOC.querySelector('#ID_main_content'));
    _ro.observe(_sidebar);
    return {
        Show() {
            D(_elem).AddStyle('bottom', '0px');
        },
        Hide() {
            D(_elem).AddStyle('bottom', `${_WIDGET_TOOL_BOTTOM_}px`);
        },
        SetAction(clickFn) {
            _elem.onclick = e => {
                D(e.target);
                while(D.HasTarget()) {
                    if(D.GetNodeName() === "BUTTON") {
                        clickFn(D.GetID());
                        return;
                    }
                    D.SetParentAsTarget();
                }
            }
        },
        get element() {return _elem;}
    }
}

export function UIPageAction(propertyFn, createFn) {
    const _elem = _DOC.querySelector('#ID_main_action');
    const _actionElem = D(_elem).Qe('[page-action]');
    _actionElem.onclick = e => {
        if(D(e.target).HasAttribute('page-property')) {
            propertyFn && propertyFn();
        } else if(D.HasAttribute('page-create')) {
            createFn && createFn();
        }
    }
    return {
        Show() {
        },
        Hide() {
        },
        Release() {
            _actionElem.onclick = undefined;
        }
    }
}

export function UIPageProperty() {
    const _elem = _DOC.querySelector('#ID_main_summary');
    const _styleSwitcher = D(_elem).StyleSwitcher('display', 'none');
    return {
        Show() {
            _styleSwitcher.Restore();
        },
        Hide() {
            _styleSwitcher.Do();
        },
        SetData(caption, modifyTime, description) {
            D(_elem).Qe('[page-time]').innerText = modifyTime;
            D.Qe('[page-title]').innerText = caption;
            D.Qe('[page-desc]').innerText = description;
        },
        Release() {
        }
    }
}


const _TOC_MARKER_ = 'TOC-item';
const _MAP_CLASS_NAME_ = new Map();
_MAP_CLASS_NAME_.set('H1', 1);
_MAP_CLASS_NAME_.set('H2', 2);
_MAP_CLASS_NAME_.set('H3', 3);
function _AddTocMarker(elem, tag) {
    const _arr = elem.querySelectorAll(tag);
    _arr.forEach((elem) => {
        D(elem).AddAttribute(_TOC_MARKER_, '');
    });
}
function CreateTOCList(el) {
    const _arr = el.querySelectorAll(`[${_TOC_MARKER_}]`);
    if(_arr.length <= 0) return null;
    const _ul = _InstantiateElement('#ID_tpl_toc', true, 0);
    for(let i = 0, N = _arr.length; i < N; ++i) {
        const _e = _arr[i];
        if(!_e.id) _e.id = _GenID();
        const _li = _InstantiateElement('#ID_tpl_toc', true, _MAP_CLASS_NAME_.get(_e.nodeName));
        D(_li).QeC('a').AddAttribute('href', `#${_e.id}`).SetInnerText(_e.innerText);
        _ul.append(_li);
    }
    return _ul;
}
export function UIPageTOC() {
    const _elem = _DOC.querySelector('#ID_main_toc');
    const _elemTOC = D(_elem).Qe('[toc-content]');
    const _styleSwitcher = D(_elem).StyleSwitcher('display', 'none');
    return {
        Show() {
            _styleSwitcher.Restore();
        },
        Hide() {
            _styleSwitcher.Do();
        },
        Clear() {
            _elemTOC.replaceChildren();
        },
        Add(element) {
            _elemTOC.append(element);
        },
        Remove(element) {
            element.remove();
        },
        GenerateTocElement(element) {
            _AddTocMarker(element, 'h1');
            _AddTocMarker(element, 'h2');
            _AddTocMarker(element, 'h3');
            return CreateTOCList(element);
        },
        Release() {}
    }
}

export function UISidebar() {
    const _elem = _DOC.querySelector('#ID_sidebar');
    _elem.ontransitionend = e => {
        D(_elem).RemoveClass('transition-width');
    };
    let _width;
    let _status = true;
    const _elemMenuList = D(_elem).Qe('[sidebar-menu-list]');
    const _uiToggleBtn = UIToggleButton('[sidebar-menu-list] > button[data-slog-menu="toggle"]', _status);
    _uiToggleBtn.element.onclick = e => {
        if(_status) {
            _uiToggleBtn.Off();
            _width = D(_elem).GetStyle("width");
            D.AddClass('transition-width').AddStyle("width", '40px');
            _draggerElem.Disable();
        } else {
            _uiToggleBtn.On();
            D(_elem).AddClass('transition-width').AddStyle('width', _width);
            _draggerElem.Enable();
        }
        _status = !_status;
    }
    const _draggerElem = UIDragger(D(_elem).Qe("#ID_sidebar_dragger"), _elem, UIDraggerDirection.RIGHT, 46, 550, true);
    return {
        Show() {},
        Hide() {},
        get menuListElement() {return _elemMenuList;},
        Release() {
            _uiToggleBtn.element.onclick = undefined;
            _elem.ontransitionend = undefined;
        }
    }
}


const _NAME_TPL_TAG_ = '#ID_tpl_tag';
function _FindUITagWithNameAndRemove(mapTagElem, elem) {
    mapTagElem.delete(elem._tagName);
    elem.firstElementChild && (elem.firstElementChild.onclick = undefined);
    elem.remove();
}

function _CreateTagElementAndSave(name, mapElem, pivot, deleteFn) {
    const _elem = _InstantiateElement(_NAME_TPL_TAG_, true, 0);
    _elem.innerText = name;
    if(deleteFn) {
        let _e = _InstantiateElement(_NAME_TPL_TAG_, true, 1);
        _elem.append(_e);
        _e.onclick = deleteFn;
    }
    mapElem.set(name, _elem);
    pivot.before(_elem);
    _elem._tagName = name;
    return _elem;
}

export function UITagGroup(editable) {
    const _elem = _InstantiateElement(_NAME_TPL_TAG_, true, 2);

    const _MAX_CHAR_ = 16;
    const _MIN_CHAR_ = 4
    const _mapTagElem = new Map();

    let _tagDeleteBtnCb = undefined;
    let _pivot;
    if(editable) {
        _tagDeleteBtnCb = e => {
            let _tmp = e.target;
            while(_tmp) {
                if(D(_tmp).HasAttribute("tag-item")) {
                    _FindUITagWithNameAndRemove(_mapTagElem, _tmp);
                    return;
                }
                _tmp = _tmp.parentElement;
            }
        };
        _pivot = _DOC.createElement('input');
        D(_pivot).AddStyle("outline", 'none');
        D.AddStyle('background', 'transparent');
        D.AddStyle('cursor', 'default');
        //D.AddStyle('width', `${16 * _MIN_CHAR_}px`);
        D.AddAttribute('type', 'text');
        D.AddAttribute('minlength', _MIN_CHAR_);
        D.AddAttribute('maxlength', _MAX_CHAR_);
        D.AddAttribute('size', 1);
        _pivot.onkeypress = e => {
            if(e.charCode === 13) {
                _CreateTagElementAndSave(_pivot.value, _mapTagElem, _pivot, _tagDeleteBtnCb);
                D(_pivot).SetInputValue('');
                D.AddAttribute('size', 1);
            }
        }
        _pivot.oninput = _ => {
            const _w = _pivot.value.length;
            D(_pivot).AddAttribute('size', _w);
        }
        _elem.onclick = _ => {
            _pivot.focus();
        }
    } else {
        _pivot = _DOC.createElement('span');
    }
    _elem.append(_pivot);

    return {
        Add(arrTag) {
            for(let i = 0, N = arrTag.length; i < N; ++i) {
                _CreateTagElementAndSave(arrTag[i], _mapTagElem, _pivot, _tagDeleteBtnCb);
            };
        },
        Remove() {
            _mapTagElem.forEach((elem) => {
                _FindUITagWithNameAndRemove(_mapTagElem, elem);
            });
            _mapTagElem.clear();
        },
        GetNames(outArr) {
            _mapTagElem.forEach((_, name) => {
                outArr.push(name);
            });
        },
        Release() {
            _elem.remove();
            _elem.onclick = undefined;
            _pivot.oninput = undefined;
            _pivot.onkeypress = undefined;
        },
        get element() {return _elem;}
    }

}


export function UIContentMenu() {
    const _elem = _DOC.querySelector('#ID_main_content_menu');
    const _collaper = Collapser(_elem, D(_elem).Qe('[main-menu-content]'), UICollapserTriggerType.ENTER);
    /*
    D.Qe('[main-menu-up]').onclick = e => {
        document.body.scrollTo(0, 0);// = 0; // For Safari
        document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
    }
    */
    return {
        Show() {
            _collaper.Expand();
        },
        Hide() {
            _collaper.Collapse();
        },
    }
}

export function UIViewPaneHTML() {
    const _elem = _InstantiateElement('ID_tpl_view_pane');
    return {
        get element() {return _elem;},
        SetHTML(str) {
            _elem.innerHTML = str;
        }
    }
}

export function UIViewPaneText() {
    const _elem = _InstantiateElement('ID_tpl_view_pane');
    return {
        get element() {return _elem;},
        SetText(text) {
            _elem.innerText = text;
        }
    }
}

export function UIViewPaneImage() {
    const _elem = _InstantiateElement('ID_tpl_view_pane_img');
    return {
        get element() {return _elem;},
        SetCaption(text) {
            D(_elem).Qe('figcaption').innerText = text;
        },
        SetSource(url) {
            D(_elem).Qe('img').src = url;
        },
    }
}

export function UIEditPaneText() {
    const _elem = _InstantiateElement('ID_tpl_edit_pane_text');
    const _textarea = D(_elem).Qe('div[contenteditable]');
    return {
        get element() {return _elem;},
        SetText(text) {
            _textarea.innerText = text;
        },
        GetText() {
            return _textarea.innerText;
        }
    }
}

export function UIEditPaneUpload() {
    const _elem = _InstantiateElement('ID_tpl_edit_pane_upload');
    return {
        get element() {return _elem;},
    }
}

export function UIWidget(elementID) {
    const _elem = _InstantiateElement('#ID_tpl_widget');
    D(_elem).SetID(elementID);
    const _con = D(_elem).Qe("[ui-content]");
    let _uiPane;

    return {
        get element() {return _elem;},
        SetAction(createFn, toggleFn, contentFn) {
            let _target;
            _elem.onclick = e => {
                _target = e.target;
                while(D(_target)) {
                    if(D.HasAttribute('ui-create')) {
                        createFn && createFn(elementID, e);
                        return;
                    }
                    if(D.HasAttribute('ui-toggle')) {
                        toggleFn && toggleFn(elementID, e);
                        return;
                    }
                    if(contentFn) {
                        if(D.HasAttribute('ui-content')) {
                            contentFn(elementID, e);
                            return;
                        }
                    }
                    _target = _target.parentElement;
                    if(_target === _elem) break;
                }
            }
        },
        SetPane(pane) {
            if(pane === _uiPane) return false;
            if(_uiPane) {
                _uiPane.element.replaceWith(pane.element);
            } else {
                _con.append(pane.element);
            }
            _uiPane = pane;
            return true;
        },
        Release() {
            _uiPane = undefined;
            _con.replaceChildren();
            _elem.remove();
            _elem.onclick = undefined;
        },
    };
}

export function UIWidgetGroup() {
    const _elem = _BODY.querySelector('#ID_main_content_group');

    return {
        get element() {return _elem;},

        InsertWidgetElement(uiWidget, index) {
            uiWidget.element.remove();
            const _pivot = _elem.children[index];
            if(_pivot) {
                _pivot.before(uiWidget.element);
            } else {
                _elem.append(uiWidget.element);
            }
        },

        RemoveAll() {
            _elem.replaceChildren();
        },

        Release() {
            RemoveAll();
        },
    };
}

export function UIPaneView() {
    const _elem = _InstantiateElement('#ID_tpl_view_pane');

    return {
        get element() {return _elem;},
        SetText(text) {_elem.innerText = text;},
        SetHTML(html) {_elem.innerHTML = html;},
        Release() {},
    };
}

export function UIPaneViewImage() {
    const _elem = _InstantiateElement('#ID_tpl_view_pane_img');

    return {
        get element() {return _elem;},
        SetSource(src) {
            D(_elem).Qe('img').src = src;
        },
        SetCaption(caption) {
            D(_elem).Qe('figcaption').innerHTML = caption;
        },
        Release() {},
    };
}

export function UIPaneViewCode() {
    const _elem = _InstantiateElement('#ID_tpl_view_pane_code');

    return {
        get element() {return _elem;},
        SetText(text) {D(_elem).Qe('code').innerText = text;},
        SetHTML(html) {D(_elem).Qe('code').innerHTML = html;},
        SetLanguage(lang) {
            D(_elem).QeC('pre').AddClass(`language-${lang}`);
        },
        Release() {},
    };
}

export function UIPaneEdit() {
    const _elem = _InstantiateElement('#ID_tpl_edit_pane');

    return {
        get element() {return _elem;},
        SetText(text) {_elem.innerText = text;},
        Release() {},
        Focus() {
            D(_elem).AddClass('slog_pane_focus');
        },
        Blur() {
            D(_elem).RemoveClass('slog_pane_focus');
        },
    };
}

const _ARRAY_WIDGETS_ = Object.freeze([
    {type: WIDGET_TYPE.HTML, name: 'HTML', desc: 'you can use what ever you want HTML tags to layout your article'},
    {type: WIDGET_TYPE.MARKDOWN, name: 'MARKDOWN', desc: 'you can use what ever you want HTML tags to layout your article'},
    {type: WIDGET_TYPE.TEXT, name: 'TEXT', desc: 'you can use what ever you want HTML tags to layout your article'},
    {type: WIDGET_TYPE.CODE, name: 'CODE', desc: 'you can use what ever you want HTML tags to layout your article'},
]);
export function UISelector() {
    const _elem = _InstantiateElement('#ID_tpl_selector', false, 0);
    const _modal = UIModal(_elem, true);
    for(let i = 0, N = _ARRAY_WIDGETS_.length; i < N; ++i) {
        let _item = _InstantiateElement('#ID_tpl_selector', true, 0);
        D(_item).Qe('[selector-name]').textContent = _ARRAY_WIDGETS_[i].name;
        D.Qe('[selector-disc]').textContent = _ARRAY_WIDGETS_[i].desc;
        D.AddAttribute('selector-type', _ARRAY_WIDGETS_[i].type);
        _elem.append(_item);
    }

    const Show = () => {_modal.Show();}
    const Hide = () => {_modal.Hide();}
    return {
        Show, Hide,
        get closeBtn() {return _modal.closeBtn;},
        get element() {return _elem;},
    }
}
